/*
 *HTTPManager.java
 *
 * Copyright(c) IronOne Technologies (Pvt) Ltd.  All Rights Reserved.
 * This software is the proprietary information of IronOne Technologies (Pvt) Ltd.
 *
 */
package com.ironone.streaming.comm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import android.util.Log;

import com.ironone.streaming.lite.R;
import com.ironone.streaming.application.FormObject;
import com.ironone.streaming.application.MainApplication;
import com.ironone.streaming.model.EventsDataModel;
import com.ironone.streaming.model.OurShowsDataModel;
import com.ironone.streaming.model.RequestDataModel;
import com.ironone.streaming.model.ResponseDataModel;

/**
 * {This class handles the http connection}
 * 
 * @Created on Apr 22, 2013 : 1:07:59 PM
 * @author Suren Manawatta
 */
public class HTTPManager {
	String xml;
	Context context;
	// Set the timeout in milliseconds until a connection is established.
	// The default value is zero, that means the timeout is not used.
	// previous val: 10000
	int con_timeout = 10000;

	// Set the default socket timeout (SO_TIMEOUT)
	// in milliseconds which is the timeout for waiting for data.
	// previous val: 15000
	int so_timeout = 12000;

	public HTTPManager(Context context) {
		this.context = context;
	}

	/**
	 * @return This method request XML from the server and returns it
	 * @throws TimeoutException
	 */
	public ResponseDataModel getXmlFromUrl() {
		try {
			// return new HttpMnagerAsync().execute().get(con_timeout,
			// TimeUnit.MILLISECONDS);
			MyTaskParams params = new MyTaskParams(xml, null);
			return HttpMnagerExecute(params);
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	/**
	 * @return This method request JSON from the server and returns it
	 * @throws TimeoutException
	 */
	public ResponseDataModel getInitServiceData() {
		try {
			String initUrl = new URL(context).getInitializeSvcURL();
			String apikey = context.getResources().getString(R.string.apikey);
			int dataVer = FormObject.getInstance().getDataVersion();

			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
			nameValuePairs.add(new BasicNameValuePair("api_key", apikey));
			nameValuePairs.add(new BasicNameValuePair("data_ver", Integer.toString(dataVer)));
			//nameValuePairs.add(new BasicNameValuePair("data_ver", "1"));
			MyTaskParams params = new MyTaskParams(initUrl, nameValuePairs);
			// return new HttpMnagerAsync().execute(params).get(timeout,
			// TimeUnit.MILLISECONDS);
			ResponseDataModel rdm = HttpMnagerExecute(params);
			/**
			 * JSONObject json = rdm.responseData; String sinitjson =
			 * json.toString(); String snowjson =
			 * sinitjson.substring(sinitjson.indexOf("{"),
			 * sinitjson.lastIndexOf("}") + 1);
			 * Log.e("sb in getInitServiceData",snowjson); rdm.responseData =
			 * new JSONObject(snowjson);
			 */
			return rdm;
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	/**
	 * @return This method send facebook user data to the server
	 * @throws TimeoutException
	 */
	public ResponseDataModel sendFacebookUserData() {
		try {
			String loginUrl = new URL(context).getLoginSvcURL();
			String accessToken = FormObject.getInstance().getAccessToken();

			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
			nameValuePairs.add(new BasicNameValuePair("access_token",
					accessToken));
			nameValuePairs.add(new BasicNameValuePair("name", FormObject
					.getInstance().getFbName()));
			nameValuePairs.add(new BasicNameValuePair("fb_id", FormObject
					.getInstance().getFbUserId()));
			nameValuePairs.add(new BasicNameValuePair("email", FormObject
					.getInstance().getFbEmail()));
			nameValuePairs.add(new BasicNameValuePair("birthday", FormObject
					.getInstance().getFbBirthday()));
			nameValuePairs.add(new BasicNameValuePair("location", FormObject
					.getInstance().getFbLocation()));
			nameValuePairs.add(new BasicNameValuePair("gender", FormObject
					.getInstance().getFbGender()));
			nameValuePairs.add(new BasicNameValuePair("mobile", ""));
			nameValuePairs.add(new BasicNameValuePair("page_like", FormObject
					.getInstance().getFbMusicLiked()));

			MyTaskParams params = new MyTaskParams(loginUrl, nameValuePairs);
			ResponseDataModel rdm = HttpMnagerExecute(params);
			return rdm;
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	/**
	 * @return This method get our shows data from the server
	 * @throws TimeoutException
	 */
	public ResponseDataModel getOurShowsData() {
		try {
			String showsUrl = new URL(context).getShowsSvcURL();
			String accessToken = FormObject.getInstance().getAccessToken();

			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
			nameValuePairs.add(new BasicNameValuePair("access_token",
					accessToken));

			MyTaskParams params = new MyTaskParams(showsUrl, nameValuePairs);

			ResponseDataModel rdm = HttpMnagerExecute(params);
			return rdm;
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	/**
	 * @return This method get events data from the server
	 * @throws TimeoutException
	 */
	public ResponseDataModel getEventsData() {
		try {
			String eventsUrl = new URL(context).getEventsSvcURL();
			String accessToken = FormObject.getInstance().getAccessToken();

			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
			nameValuePairs.add(new BasicNameValuePair("access_token",
					accessToken));

			MyTaskParams params = new MyTaskParams(eventsUrl, nameValuePairs);
			// return new HttpMnagerAsync().execute(params).get(con_timeout,
			// TimeUnit.MILLISECONDS);
			ResponseDataModel rdm = HttpMnagerExecute(params);
			return rdm;
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	/**
	 * @return This method get now playing data from the server
	 * @throws TimeoutException
	 */
	public ResponseDataModel getNowPlayingData() {
		try {
			String nowPlayingUrl = new URL(context).getNowPlayingSvcURL();
			String accessToken = FormObject.getInstance().getAccessToken();

			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
			nameValuePairs.add(new BasicNameValuePair("access_token",
					accessToken));

			MyTaskParams params = new MyTaskParams(nowPlayingUrl,
					nameValuePairs);

			ResponseDataModel rdm = HttpMnagerExecute(params);
			return rdm;
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	/**
	 * @return This method get server date and time data from the server
	 * @throws TimeoutException
	 */
	public ResponseDataModel getDateTimeData() {
		try {
			String timeUrl = new URL(context).getTimeSvcURL();

			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);

			MyTaskParams params = new MyTaskParams(timeUrl, nameValuePairs);

			// return new HttpMnagerAsync().execute(params).get(con_timeout,
			// TimeUnit.MILLISECONDS);
			ResponseDataModel rdm = HttpMnagerExecute(params);
			return rdm;
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	public List<OurShowsDataModel> downloadOurShowsImages(Activity act,
			List<OurShowsDataModel> showData) {
		for (OurShowsDataModel ourShowsDataModel : showData) {
			try {
				if (ourShowsDataModel.imageLink != null) {
					// Option 1
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 2;
					byte[] img = MainApplication
							.getBitmapToByteArr(BitmapFactory.decodeStream(
									ourShowsDataModel.imageLink
											.openConnection().getInputStream(),
									null, options));
					ourShowsDataModel.image = img;

					// Option 2
					/*
					 * BitmapFactory.Options options = new
					 * BitmapFactory.Options(); options.inJustDecodeBounds =
					 * true; InputStream imgStream =
					 * ourShowsDataModel.imageLink.
					 * openConnection().getInputStream(); Bitmap bitmap =
					 * BitmapFactory.decodeStream(imgStream, null, options);
					 * //int imageHeight = options.outHeight; int imageWidth =
					 * options.outWidth; //String imageType =
					 * options.outMimeType;
					 * 
					 * // Recreate the stream options.inJustDecodeBounds =
					 * false; int sSize = (int)(imageWidth / scrnWidthNeeded);
					 * if (sSize <= 0) sSize = 1; options.inSampleSize = 2;
					 * ourShowsDataModel.image =
					 * BitmapFactory.decodeStream(imgStream, null, options);
					 */
				}
			} catch (Exception e) {
				ourShowsDataModel.image = null;
				continue;
			}
		}
		return showData;
	}

	public List<EventsDataModel> downloadEventsImages(Activity act,
			List<EventsDataModel> eventsData) {
		for (EventsDataModel ourEventsDataModel : eventsData) {
			try {
				if (ourEventsDataModel.imageLink != null) {
					// Option 1
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 2;

					byte[] img = MainApplication
							.getBitmapToByteArr(BitmapFactory.decodeStream(
									ourEventsDataModel.imageLink
											.openConnection().getInputStream(),
									null, options));
					ourEventsDataModel.image = img;

					// Option 2
					/*
					 * BitmapFactory.Options options = new
					 * BitmapFactory.Options(); options.inJustDecodeBounds =
					 * true; InputStream imgStream =
					 * ourShowsDataModel.imageLink.
					 * openConnection().getInputStream(); Bitmap bitmap =
					 * BitmapFactory.decodeStream(imgStream, null, options);
					 * //int imageHeight = options.outHeight; int imageWidth =
					 * options.outWidth; //String imageType =
					 * options.outMimeType;
					 * 
					 * // Recreate the stream options.inJustDecodeBounds =
					 * false; int sSize = (int)(imageWidth / scrnWidthNeeded);
					 * if (sSize <= 0) sSize = 1; options.inSampleSize = 2;
					 * ourShowsDataModel.image =
					 * BitmapFactory.decodeStream(imgStream, null, options);
					 */
				}
			} catch (Exception e) {
				ourEventsDataModel.image = null;
				continue;
			}
		}
		return eventsData;
	}

	public void downloadAlbumArtImage(Activity act, java.net.URL imageLink) {
		try {
			if (imageLink != null) {
				// Option 1
				BitmapFactory.Options options = new BitmapFactory.Options();
				options.inSampleSize = 2;

				Bitmap temp = BitmapFactory.decodeStream((imageLink)
						.openConnection().getInputStream(), null, options);
				if (temp == null
						&& FormObject.getInstance().getAlbumArtImage() != null)
					FormObject.getInstance().setAlbumArtImage(
							FormObject.getInstance().getAlbumArtImage());
				else
					FormObject.getInstance().setAlbumArtImage(
							MainApplication.getBitmapToByteArr(temp));

				// Option 2
				/*
				 * BitmapFactory.Options options = new BitmapFactory.Options();
				 * options.inJustDecodeBounds = true; InputStream imgStream =
				 * ourShowsDataModel
				 * .imageLink.openConnection().getInputStream(); Bitmap bitmap =
				 * BitmapFactory.decodeStream(imgStream, null, options); //int
				 * imageHeight = options.outHeight; int imageWidth =
				 * options.outWidth; //String imageType = options.outMimeType;
				 * 
				 * // Recreate the stream options.inJustDecodeBounds = false;
				 * int sSize = (int)(imageWidth / scrnWidthNeeded); if (sSize <=
				 * 0) sSize = 1; options.inSampleSize = 2;
				 * ourShowsDataModel.image =
				 * BitmapFactory.decodeStream(imgStream, null, options);
				 */
			}
		} catch (Exception e) {
			FormObject.getInstance().setAlbumArtImage(null);
		}
	}

	public ResponseDataModel sendRequestData(RequestDataModel rdm) {
		try {
			String reqUrl = new URL(context).getRequestSvcURL();
			String accessToken = FormObject.getInstance().getAccessToken();
			String tnlId = FormObject.getInstance().getTNLId();

			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
			nameValuePairs.add(new BasicNameValuePair("access_token",
					accessToken));
			nameValuePairs.add(new BasicNameValuePair("tnl_id", tnlId));

			// nameValuePairs.add(new BasicNameValuePair("show_name",
			// rdm.reqesterName));
			nameValuePairs.add(new BasicNameValuePair("requester_name",
					rdm.reqesterName));
			nameValuePairs
					.add(new BasicNameValuePair("song_name", rdm.songName));
			nameValuePairs
					.add(new BasicNameValuePair("song_artist", rdm.artist));
			nameValuePairs.add(new BasicNameValuePair("dedication",
					rdm.dedication));

			MyTaskParams params = new MyTaskParams(reqUrl, nameValuePairs);

			ResponseDataModel rdm2 = HttpMnagerExecute(params);
			return rdm2;
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		}
	}

	/*
	 * public class HttpMnagerAsync extends AsyncTask<MyTaskParams, Void,
	 * ResponseDataModel> {
	 * 
	 * @Override protected ResponseDataModel doInBackground(MyTaskParams...
	 * params) {
	 * 
	 * ResponseDataModel resDataModel = new ResponseDataModel(); InputStream
	 * inputStream = null; BufferedReader reader = null; try {
	 * //Thread.sleep(3000); String URL = params[0].URL; List<NameValuePair> nvp
	 * = params[0].nameValuePairs;
	 * 
	 * HttpParams paramss = new BasicHttpParams();
	 * HttpConnectionParams.setConnectionTimeout(paramss, so_timeout);
	 * HttpConnectionParams.setSoTimeout(paramss, so_timeout);
	 * 
	 * HttpPost httpPost = new HttpPost(URL);
	 * //context.getResources().getString(R.string.url)
	 * httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
	 * httpPost.setEntity(new UrlEncodedFormEntity(nvp));
	 * 
	 * DefaultHttpClient httpClient = new DefaultHttpClient(); HttpResponse
	 * httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity =
	 * httpResponse.getEntity(); inputStream = httpEntity.getContent();
	 * 
	 * // JSON is UTF-8 by default reader = new BufferedReader(new
	 * InputStreamReader(inputStream, "UTF-8"), 8); StringBuilder sb = new
	 * StringBuilder();
	 * 
	 * String line = null; while ((line = reader.readLine()) != null) {
	 * sb.append(line + "\n"); }
	 * 
	 * resDataModel.responseData = new JSONObject(sb.toString()); return
	 * resDataModel; } catch(IOException io){ return
	 * errorHandler(context.getString(R.string.error_io)); }catch (JSONException
	 * jo) { return
	 * errorHandler(context.getString(R.string.error_jsonexception)); } catch
	 * (Exception e) { return
	 * errorHandler(context.getString(R.string.error_general)); }finally { try {
	 * if(inputStream != null) inputStream.close(); if(reader != null)
	 * reader.close(); } catch (Exception e) { e.printStackTrace(); } } }
	 * 
	 * @Override protected void onPostExecute(ResponseDataModel mod) { } }
	 */

	/**
	 * @return This method get server data behalf of all other functions
	 * @throws ConnectTimeoutException
	 * @throws IOException
	 * @throws JSONException
	 * @throws Exception
	 */
	protected ResponseDataModel HttpMnagerExecute(MyTaskParams... params) {
		ResponseDataModel resDataModel = new ResponseDataModel();
		InputStream inputStream = null;
		BufferedReader reader = null;
		try {
			// Thread.sleep(3000);
			String URL = params[0].URL;
			List<NameValuePair> nvp = params[0].nameValuePairs;

			HttpParams paramss = new BasicHttpParams();

			// Set the timeout in milliseconds until a connection is
			// established.
			// The default value is zero, that means the timeout is not used.
			HttpConnectionParams.setConnectionTimeout(paramss, con_timeout);

			// Set the default socket timeout (SO_TIMEOUT)
			// in milliseconds which is the timeout for waiting for data.
			HttpConnectionParams.setSoTimeout(paramss, so_timeout);

			HttpPost httpPost = new HttpPost(URL); // context.getResources().getString(R.string.url)
			httpPost.setHeader("Content-type",
					"application/x-www-form-urlencoded");
			httpPost.setEntity(new UrlEncodedFormEntity(nvp));

			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			inputStream = httpEntity.getContent();

			// JSON is UTF-8 by default
			reader = new BufferedReader(new InputStreamReader(inputStream,
					"UTF-8"), 8);
			StringBuilder sb = new StringBuilder();

			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
			//Helani
			Log.e("sb", sb.toString());
			resDataModel.responseData = new JSONObject(sb.toString());
			/*
			String json = sb.toString();
            resDataModel.responseData = new JSONObject(json.substring(json.indexOf("{"), json.lastIndexOf("}") + 1));*/
			return resDataModel;

		} catch (ConnectTimeoutException e) {
			return errorHandler(context.getString(R.string.error_timeout));
		} catch (IOException io) {
			return errorHandler(context.getString(R.string.error_io));
		} catch (JSONException jo) {
			return errorHandler(context.getString(R.string.error_jsonexception));
		} catch (Exception e) {
			return errorHandler(context.getString(R.string.error_general));
		} finally {
			try {
				if (inputStream != null)
					inputStream.close();
				if (reader != null)
					reader.close();
				//return resDataModel;
			} catch (Exception e) {

				//return errorHandler(context.getString(R.string.error_general));
			}
		}
	}

	
	protected ResponseDataModel errorHandler(String errMsg) {
		ResponseDataModel resDataModel = new ResponseDataModel();
		resDataModel.isError = true;
		resDataModel.errorMessage = errMsg;
		resDataModel.responseData = null;
		return resDataModel;
	}

	static class MyTaskParams {
		String URL = "";
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

		MyTaskParams(String pURL, List<NameValuePair> nvPairs) {
			this.URL = pURL;
			this.nameValuePairs = nvPairs;
		}
	}
	
	
}